<!DOCTYPE html>

<!--
                           _ooOoo_
                          o8888888o
                          88" . "88
                          (| -_- |)
                          O\  =  /O
                       ____/`---'\____
                     .'  \\|     |//  `.
                    /  \\|||  :  |||//  \
                   /  _||||| -:- |||||-  \
                   |   | \\\  -  /// |   |
                   | \_|  ''\---/''  |   |
                   \  .-\__  `-`  ___/-. /
                 ___`. .'  /--.--\  `. . __
              ."" '<  `.___\_<|>_/___.'  >'"".
             | | :  `- \`.;`\ _ /`;.`/ - ` : | |
             \  \ `-.   \_ __\ /__ _/   .-` /  /
        ======`-.____`-.___\_____/___.-`____.-'======
                           `=---='
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                 佛祖保佑       永无BUG 
-->



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<link href="//mydearest.cn" rel="dns-prefetch">
<link href="//www.mydearest.cn" rel="dns-prefetch">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">





	<meta name="description" content="陈宇的博客" />






<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />

















  
  
  
  

  
    
    
  

  
    
      
    

    
  

  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|Lobster Two:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  





  <meta name="keywords" content="shell," />





  <link rel="alternate" href="/rss2.xml" title="cosyer's Blog" type="application/atom+xml" />




  
  <link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />






<meta name="description" content="脚本运行建立一个文本文件demo，以.sh结尾的或者不需要后缀都可以。 1234#!/bin/bashNUM=10printf &quot;输出数字$NUM\n&quot;echo $NUM 通过sh或者bash命令运行脚本，sh scriptname 运行一个Bash脚本将会禁止所有Bash的扩展特性。 12345# 你能够运行它用命令sh demo# 另外也也可以用bash来执行bash demo 脚本以”#!”">
<meta name="keywords" content="shell">
<meta property="og:type" content="article">
<meta property="og:title" content="Shell入门教程">
<meta property="og:url" content="http://mydearest.cn/2020/Shell入门教程.html">
<meta property="og:site_name" content="cosyer&#39;s Blog">
<meta property="og:description" content="脚本运行建立一个文本文件demo，以.sh结尾的或者不需要后缀都可以。 1234#!/bin/bashNUM=10printf &quot;输出数字$NUM\n&quot;echo $NUM 通过sh或者bash命令运行脚本，sh scriptname 运行一个Bash脚本将会禁止所有Bash的扩展特性。 12345# 你能够运行它用命令sh demo# 另外也也可以用bash来执行bash demo 脚本以”#!”">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2020-04-28T17:18:01.534Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Shell入门教程">
<meta name="twitter:description" content="脚本运行建立一个文本文件demo，以.sh结尾的或者不需要后缀都可以。 1234#!/bin/bashNUM=10printf &quot;输出数字$NUM\n&quot;echo $NUM 通过sh或者bash命令运行脚本，sh scriptname 运行一个Bash脚本将会禁止所有Bash的扩展特性。 12345# 你能够运行它用命令sh demo# 另外也也可以用bash来执行bash demo 脚本以”#!”">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    sidebar: {"position":"left","display":"always","offset":12,"offset_float":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://mydearest.cn/2020/Shell入门教程.html"/>





  <title>Shell入门教程 | cosyer's Blog</title>
  





  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?653a4be35cb6c7b26817038a17c3f0d6";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>











  
<link href="https://mydearest.cn/css/all-9097fb9016.css" rel="stylesheet" type="text/css">
<style>
// scrollbar滚动条样式优化

::-webkit-scrollbar-corner {
  background-color: transparent;
}

::-webkit-scrollbar-button {
  width: 0;
  height: 0;
  display: none;
}

::-webkit-scrollbar-thumb {
  width: 7px;
  background-color: #b4babf;
  border-radius: 7px;
}

::-webkit-scrollbar {
  width: 7px;
  height: 7px;
}

::-webkit-scrollbar-track {
  width: 15px;
}

::-webkit-scrollbar:hover {
  background-color: transparent;
}

* {
    cursor: url("http://cdn.mydearest.cn/blog/images/miku1.png"),auto!important
}
:active {
    cursor: url("http://cdn.mydearest.cn/blog/images/miku2.png"),auto!important
}
a:hover {
    cursor: url("http://cdn.mydearest.cn/blog/images/miku2.png"),auto!important
}
</style>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  <div id="loader">
    <div></div>
  </div>

  
  
    
  

  <div class="container sidebar-position-left page-post-detail ">
    <div class="headband"></div>
    <a href="https://github.com/cosyer" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; left: 0; transform: scale(-1, 1);" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style></a>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">cosyer's Blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <h1 class="site-subtitle" itemprop="description">Blog</h1>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" class="faa-parent animated-hover" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home faa-wrench"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-links">
          <a href="/links/" class="faa-parent animated-hover" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-link faa-shake"></i> <br />
            
            友链
          </a>
        </li>
      
        
        <li class="menu-item menu-item-guestbook">
          <a href="/guestbook/" class="faa-parent animated-hover" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-comment-o faa-tada"></i> <br />
            
            留言板
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" class="faa-parent animated-hover" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive faa-float"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" class="faa-parent animated-hover" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user faa-horizontal"></i> <br />
            
            关于
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger faa-parent animated-hover">
          
            
              <i class="menu-item-icon fa fa-search faa-burst fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-date" data-datetime="2020-04-29T01:18:01+08:00">
    <div class="post-time-text">4月</div>
    <div class="post-time-count">29</div>
    <div class="text-desc">
			<div class="date-text">更新于</div>
      <div class="post-tiem">4月29</div>
      <div class="post-year">2020</div>
		</div>
  </div>
  
  
  

  <div class="post-badge">
    
            <span class="post-category" >
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/工具/" itemprop="url" rel="index">
                    <span itemprop="name">工具</span>
                  </a>
                </span>

                
                
              
            </span>
    
  </div>

  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://mydearest.cn/2020/Shell入门教程.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="陈宇（cosyer）">
      <meta itemprop="description" content="不去做的话永远也做不到。">
      <meta itemprop="image" content="/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="cosyer's Blog">
    </span>

    
      <header class="post-header">

        
        
          <h2 class="post-title" itemprop="name headline">Shell入门教程</h2>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="发表于" itemprop="dateCreated datePublished" datetime="2020-03-23T01:51:18+08:00">
                2020-03-23
              </time>
            

            

            
          </span>

          


          
            
          

          
          
             <span id="/2020/Shell入门教程.html" class="leancloud_visitors" data-flag-title="Shell入门教程">
               <span class="post-meta-divider">|</span>
               <span class="post-meta-item-icon">
                 <i class="fa fa-eye"></i>
               </span>
               
                 <span class="post-meta-item-text">热度 </span>
               
                 <span class="leancloud-visitors-count"></span> ℃
             </span>
          

          


          
            <div class="post-wordcount">
              
                
                  <span class="post-meta-divider">|</span>
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-pencil-square-o"></i>
                </span>
                
                  <span class="post-meta-item-text">字数统计：</span>
                
                <span title="字数统计：">
                  8,498 (字)
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">阅读时长：</span>
                
                <span title="阅读时长：">
                  34 (分钟)
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h2 id="脚本运行"><a href="#脚本运行" class="headerlink" title="脚本运行"></a>脚本运行</h2><p>建立一个文本文件demo，以.sh结尾的或者不需要后缀都可以。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line">NUM=10</span><br><span class="line">printf "输出数字$NUM\n"</span><br><span class="line">echo $NUM</span><br></pre></td></tr></table></figure></p>
<p>通过sh或者bash命令运行脚本，sh scriptname 运行一个Bash脚本将会禁止所有Bash的扩展特性。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 你能够运行它用命令</span></span><br><span class="line">sh demo</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 另外也也可以用bash来执行</span></span><br><span class="line">bash demo</span><br></pre></td></tr></table></figure></p>
<p>脚本以”#!”行开头，行将会命令解释器(sh或是bash)。<code>#!/bin/rm</code> 当你运行这个脚本时，除了这个脚本消失了之外，你不会发现更多其他的东西。</p>
<h2 id="注释"><a href="#注释" class="headerlink" title="注释"></a>注释</h2><p>以#开头的行就是注释，会被解释器忽略。注释行前面也可以有空白字符。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 这是一个注释</span></span><br></pre></td></tr></table></figure></p>
<h2 id="命令分隔符"><a href="#命令分隔符" class="headerlink" title="命令分隔符"></a>命令分隔符</h2><p>分号;命令分割符，分割符允许在同一行里有两个或更多的命令。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">echo hello; echo there         # 输出 hello 和 there</span><br><span class="line">filename='cosyer'               # 变量文件名</span><br><span class="line">if [ -x "$filename" ]; then    # 注意："if" and "then"需要分隔符</span><br><span class="line">  echo "File $filename exists."; cp $filename $filename.bak</span><br><span class="line">else</span><br><span class="line">  echo "File $filename not found."; touch $filename</span><br><span class="line">fi; echo "File test complete.</span><br></pre></td></tr></table></figure></p>
<h2 id="结束符"><a href="#结束符" class="headerlink" title="结束符"></a>结束符</h2><p>双分号;;，case语句分支的结束符。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">read Keypress</span><br><span class="line">case "$Keypress" in</span><br><span class="line">  [[:lower:]]   ) echo "Lowercase letter";;</span><br><span class="line">  [[:upper:]]   ) echo "Uppercase letter";;</span><br><span class="line">  [0-9]         ) echo "Digit";;</span><br><span class="line">  *             ) echo "Punctuation, whitespace, or other";;</span><br><span class="line">esac      #  允许字符串的范围出现在[]中,</span><br><span class="line">          #+ 或者POSIX风格的[[中.</span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure></p>
<hr>
<a id="more"></a>
<h2 id="句号-圆点"><a href="#句号-圆点" class="headerlink" title="句号/圆点"></a>句号/圆点</h2><p>作为一个文件名的组成部分.，当点.以一个文件名为前缀时，起作用使该文件变成了隐藏文件。这种隐藏文件ls一般是不会显示出来的。</p>
<p>作为目录名时，单个点（.）表示当前目录，两个点(..)表示上一级目录（或称为父目录）。</p>
<p>点(.)字符匹配。作为正则表达式的一部分,匹配字符时，单点（.）表示匹配任意一个字符。</p>
<h2 id="引号"><a href="#引号" class="headerlink" title="引号"></a>引号</h2><p>引号一个很重要的作用是保护命令行上的一个参数不被shell解释，而把此参数传递给要执行的程序来处理它。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">echo "$(ls -al)"</span><br></pre></td></tr></table></figure></p>
<h3 id="单引号"><a href="#单引号" class="headerlink" title="单引号"></a>单引号</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">str='this is a string'</span><br></pre></td></tr></table></figure>
<p>单引号里的任何字符都会原样输出，单引号字符串中的变量是无效的。单引号字串中不能出现单引号（对单引号使用转义符后也不行）。</p>
<h3 id="双引号"><a href="#双引号" class="headerlink" title="双引号"></a>双引号</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">your_name='cosyer'</span><br><span class="line">str="Hello, I know your are \"$your_name\"! \n"</span><br></pre></td></tr></table></figure>
<p>双引号里可以有变量，双引号里可以出现转义字符。</p>
<h2 id="命令替换"><a href="#命令替换" class="headerlink" title="命令替换"></a>命令替换</h2><p>命令替换”`”，将会重新分配一个命令甚至是多个命令的输出；它会将命令的输出如实地添加到另一个上下文中。
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">script_name=`basename $0`</span><br><span class="line">echo "The name of this script is $script_name."</span><br><span class="line"></span><br><span class="line">textfile_listing=`ls *`</span><br><span class="line"><span class="meta">#</span><span class="bash"> 变量中包含了当前工作目录下所有的*文件</span></span><br><span class="line">echo $textfile_listing</span><br></pre></td></tr></table></figure></p>
<h2 id="操作符"><a href="#操作符" class="headerlink" title="操作符"></a>操作符</h2><h3 id="赋值"><a href="#赋值" class="headerlink" title="赋值"></a>赋值</h3><p>变量赋值，初始化或改变一个变量的值，通用的变量赋值操作符，可以用于数值和字符串的赋值
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">var=27</span><br><span class="line">category=minerals  # "="字符后面不能加空白字符.</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> = 用于测试操作符</span></span><br><span class="line">if [ "$string1" = "$string2" ]</span><br><span class="line"><span class="meta">#</span><span class="bash"> <span class="keyword">if</span> [ <span class="string">"X<span class="variable">$string1</span>"</span> = <span class="string">"X<span class="variable">$string2</span>"</span> ] 会更安全,</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 它为了防止其中有一个字符串为空时产生错误信息.</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> (增加的<span class="string">"X"</span>字符可以互相抵消.) </span></span><br><span class="line">then</span><br><span class="line">   command</span><br><span class="line">fi</span><br></pre></td></tr></table></figure></p>
<h3 id="计算操作符"><a href="#计算操作符" class="headerlink" title="计算操作符"></a>计算操作符</h3><table>
<thead>
<tr>
<th>操作符</th>
<th>描述</th>
<th>操作符</th>
<th>描述</th>
<th>操作符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>+</code></td>
<td>加</td>
<td><code>/</code></td>
<td>除</td>
<td><code>**</code></td>
<td>求幂</td>
</tr>
<tr>
<td><code>-</code></td>
<td>减</td>
<td><code>*</code></td>
<td>乘</td>
<td><code>%</code></td>
<td>求模</td>
</tr>
</tbody>
</table>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> Bash在版本2.02引入了<span class="string">"**"</span>求幂操作符.</span></span><br><span class="line">let "z=5**3"</span><br><span class="line">echo "z = $z"   # z = 125</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 求模（它返回整数整除一个数后的余数）</span></span><br><span class="line">let "y=5 % 3"</span><br><span class="line">echo "y = $y"   # y = 2</span><br></pre></td></tr></table></figure>
<table>
<thead>
<tr>
<th>操作符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>+=</code></td>
<td>加等(plus-equal) 把原变量值增加一个常量并重新赋值给变量</td>
</tr>
<tr>
<td><code>-=</code></td>
<td>减等(minus-equal) 把原变量值减少一个常量并重新赋值给变量</td>
</tr>
<tr>
<td><code>*=</code></td>
<td>乘等(times-equal) 把原变量值乘上一个常量并重新赋值给变量</td>
</tr>
<tr>
<td><code>/=</code></td>
<td>除等(slash-equal) 把原变量值除以一个常量并重新赋值给变量</td>
</tr>
<tr>
<td><code>%=</code></td>
<td>模等(mod-equal) 把原变量值除以一个常量整除（即取模）并重新赋余数的值给变量</td>
</tr>
</tbody>
</table>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">let "var += 5" # 会使变量var值加了5并把值赋给var.</span><br><span class="line">let "var *= 4" # 使变量var的值乘上4并把值赋给var.</span><br></pre></td></tr></table></figure>
<h3 id="位操作符"><a href="#位操作符" class="headerlink" title="位操作符"></a>位操作符</h3><p>位操作符很少在脚本中使用。他们主要用于操作和测试从端口或sockets中读到的数据。“位运算”更多地用于编译型的语言，比如说C和C++，它们运行起来快地像飞。</p>
<table>
<thead>
<tr>
<th>操作符</th>
<th>描述</th>
<th>操作符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;&lt;</code></td>
<td>位左移（每移一位相当乘以2）</td>
<td>`</td>
<td>`</td>
<td>位或</td>
</tr>
<tr>
<td><code>&lt;&lt;=</code></td>
<td>位左移赋值</td>
<td>`</td>
<td>=`</td>
<td>位或赋值</td>
</tr>
<tr>
<td><code>&gt;&gt;</code></td>
<td>位右移（每移一位相当除以2）</td>
<td><code>~</code></td>
<td>位反</td>
</tr>
<tr>
<td><code>&gt;&gt;=</code></td>
<td>“位右移赋值”（和&lt;&lt;=相反）</td>
<td><code>!</code></td>
<td>位非</td>
</tr>
<tr>
<td><code>&amp;</code></td>
<td>位与</td>
<td><code>^</code></td>
<td>位或</td>
</tr>
<tr>
<td><code>&amp;=</code></td>
<td>位于赋值</td>
<td><code>^=</code></td>
<td>位或赋值</td>
</tr>
</tbody>
</table>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> &lt;&lt;=</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> <span class="string">"位左移赋值"</span></span></span><br><span class="line">let "var &lt;&lt;= 2" 结果使var的二进制值左移了二位（相当于乘以4）</span><br></pre></td></tr></table></figure>
<h3 id="逻辑操作符"><a href="#逻辑操作符" class="headerlink" title="逻辑操作符"></a>逻辑操作符</h3><p>逻辑与<code>&amp;&amp;</code></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">if [ $condition1 ] &amp;&amp; [ $condition2 ]</span><br><span class="line"><span class="meta">#</span><span class="bash"> 等同于:  <span class="keyword">if</span> [ <span class="variable">$condition1</span> -a <span class="variable">$condition2</span> ]</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 如果condition1和condition2都为真则返回真...</span></span><br><span class="line">fi;</span><br><span class="line"></span><br><span class="line">if [[ $condition1 &amp;&amp; $condition2 ]]    # Also works.</span><br><span class="line"><span class="meta">#</span><span class="bash"> 注意&amp;&amp;操作不能在[ ... ]结构中使用.</span></span><br><span class="line">fi;</span><br></pre></td></tr></table></figure>
<p>逻辑或<code>||</code></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">if [ $condition1 ] || [ $condition2 ]</span><br><span class="line"><span class="meta">#</span><span class="bash"> 等同于:  <span class="keyword">if</span> [ <span class="variable">$condition1</span> -o <span class="variable">$condition2</span> ]</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 如果condition1和condition2有一个为真则返回真...</span></span><br><span class="line">fi;</span><br><span class="line">if [[ $condition1 || $condition2 ]]    # Also works.</span><br><span class="line"><span class="meta">#</span><span class="bash"> 注意||操作不能在[ ... ]结构中使用.</span></span><br><span class="line">fi;</span><br></pre></td></tr></table></figure>
<p>使用&amp;&amp;和||进行混合条件测试。在算术计算的环境中，&amp;&amp;和||操作符也可以使用。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">echo $(( 1 &amp;&amp; 2 )) $((3 &amp;&amp; 0)) $((4 || 0)) $((0 || 0))</span><br><span class="line"><span class="meta">#</span><span class="bash"> 1 0 1 0</span></span><br></pre></td></tr></table></figure>
<h3 id="逗号操作符"><a href="#逗号操作符" class="headerlink" title="逗号操作符"></a>逗号操作符</h3><p>逗号<code>,</code>操作符连接两个或更多的算术操作。所有的操作都被求值(可能会有副作用)，但只返回最后一个操作的结构。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">let "t1 = ((5 + 3, 7 - 1, 15 - 4))"</span><br><span class="line">echo "t1 = $t1"               # t1 = 11</span><br><span class="line"></span><br><span class="line">let "t2 = ((a = 9, 15 / 3))"  # 初始化"a"并求"t2"的值.</span><br><span class="line">echo "t2 = $t2    a = $a"     # t2 = 5    a = 9</span><br></pre></td></tr></table></figure>
<h2 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h2><p>变量，是脚本编程中的如何进行数据表现的办法。它们可以在算术计算中作为操作数，在一个字符串表达式中作为符号表达抽象的意义或是其他的其它意义。变量是表示计算机内存中保存一种数据需要占的一个位置或一组的位置的标识。</p>
<h3 id="变量值"><a href="#变量值" class="headerlink" title="变量值"></a>变量值</h3><p>如果variable1是一个变量的名字，那么$variable1就是引用这个变量的值――即这个变量它包含的数据。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">t1=12</span><br><span class="line">echo $t1</span><br></pre></td></tr></table></figure>
<p>一个未初始化的变量有一个”null”值――表示从没有被赋值过（注意null值不等于零）。在一个变量从未赋值之前就使用它通常会引起问题。然而，仍然有可能在执行算术计算时使用一个未初始化的变量。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">echo "$uninitialized"      # (blank line)</span><br><span class="line">let "uninitialized += 5"   # Add 5 to it.</span><br><span class="line">echo "$uninitialized"      # 5</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash">  结论:</span></span><br><span class="line"><span class="meta">#</span><span class="bash">  一个未初始化的变量没有值，</span></span><br><span class="line"><span class="meta">#</span><span class="bash">  但是似乎它在算术计算中的值是零。</span></span><br><span class="line"><span class="meta">#</span><span class="bash">  这个无法证实（也可能是不可移植）的行为。</span></span><br></pre></td></tr></table></figure>
<h3 id="定义变量"><a href="#定义变量" class="headerlink" title="定义变量"></a>定义变量</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 变量名不加美元符号</span></span><br><span class="line">your_var="elaine"</span><br><span class="line"><span class="meta">#</span><span class="bash"> 重新定义</span></span><br><span class="line">your_var="newname"</span><br></pre></td></tr></table></figure>
<p><strong>注意⚠️</strong></p>
<ol>
<li>首个字符必须为字母（a-z，A-Z）。</li>
<li>中间不能有空格，可以使用下划线（_），等号左右也不能有空格。</li>
<li>不能使用标点符号。</li>
<li>不能使用bash里的关键字（可用help命令查看保留关键字）。</li>
</ol>
<h3 id="只读变量"><a href="#只读变量" class="headerlink" title="只读变量"></a>只读变量</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line">github="https://jaywcjlove.github.io"</span><br><span class="line">readonly github</span><br><span class="line">github="https://www.github.com"</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 运行脚本，结果如下：</span></span><br><span class="line">/bin/sh: NAME: This variable is read only.</span><br></pre></td></tr></table></figure>
<h3 id="使用变量"><a href="#使用变量" class="headerlink" title="使用变量"></a>使用变量</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">your_var="github"</span><br><span class="line">echo $your_var</span><br><span class="line">echo $&#123;your_var&#125;</span><br><span class="line">echo "your name is $&#123;your_var&#125;-l"</span><br></pre></td></tr></table></figure>
<h3 id="删除变量unset"><a href="#删除变量unset" class="headerlink" title="删除变量unset"></a>删除变量unset</h3><p>变量被删除后不能再次使用。unset 命令不能删除只读变量。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">myUrl="https://jaywcjlove.github.io"</span><br><span class="line">unset myUrl</span><br><span class="line">echo $myUrl</span><br></pre></td></tr></table></figure>
<h3 id="变量类型"><a href="#变量类型" class="headerlink" title="变量类型"></a>变量类型</h3><p>不同与许多其他的编程语言，Bash不以”类型”来区分变量。本质上来说，Bash变量是字符串，但是根据环境的不同，Bash允许变量有整数计算和比较。其中的决定因素是变量的值是不是只含有数字。</p>
<ol>
<li><strong>局部变量</strong> 局部变量在脚本或命令中定义，仅在当前shell实例中有效，其他shell启动的程序不能访问局部变量。</li>
<li><strong>环境变量</strong> 所有的程序，包括shell启动的程序，都能访问环境变量，有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。</li>
<li><strong>shell变量</strong> shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量，有一部分是局部变量，这些变量保证了shell的正常运行</li>
</ol>
<h3 id="内部变量"><a href="#内部变量" class="headerlink" title="内部变量"></a>内部变量</h3><table>
<thead>
<tr>
<th>内部变量</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>$BASH</td>
<td>Bash二进制程序文件的路径</td>
</tr>
<tr>
<td>$BASH_ENV</td>
<td>该环境变量保存一个Bash启动文件路径，当启动一个脚本程序时会去读该环境变量指定的文件。</td>
</tr>
<tr>
<td>$BASH_SUBSHELL</td>
<td>一个指示子shell(subshell)等级的变量。它是Bash版本3新加入的。</td>
</tr>
<tr>
<td>$BASH_VERSINFO[n]</td>
<td>这个数组含有6个元素，指示了安装的Bash版本的信息。它和$BASH_VERSION相似，但它们还是有一些小小的不同。</td>
</tr>
<tr>
<td>$BASH_VERSION</td>
<td>安装在系统里的Bash版本。</td>
</tr>
<tr>
<td>$DIRSTACK</td>
<td>在目录堆栈里面最顶端的值(它受pushd和popd的控制)</td>
</tr>
<tr>
<td>$EDITOR</td>
<td>由脚本调用的默认的编辑器，一般是vi或是emacs。</td>
</tr>
<tr>
<td>$EUID</td>
<td>有效用户ID</td>
</tr>
<tr>
<td>$FUNCNAME</td>
<td>当前函数的名字</td>
</tr>
<tr>
<td>$GLOBIGNORE</td>
<td>由通配符(globbing)扩展的一列文件名模式。</td>
</tr>
<tr>
<td>$GROUPS</td>
<td>目前用户所属的组</td>
</tr>
<tr>
<td>$HOME</td>
<td>用户的家目录，通常是/home/username</td>
</tr>
<tr>
<td>$HOSTNAME</td>
<td>在系统启动时由一个初始化脚本中用hostname命令给系统指派一个名字。然而，gethostname()函数能设置Bash内部变量E$HOSTNAME。</td>
</tr>
<tr>
<td>$HOSTTYPE</td>
<td>机器类型，像$MACHTYPE一样标识系统硬件。</td>
</tr>
<tr>
<td>$IFS</td>
<td>内部字段分隔符</td>
</tr>
<tr>
<td>$IGNOREEOF</td>
<td>忽略EOF：在退出控制台前有多少文件结尾标识（end-of-files,control-D）会被shell忽略。</td>
</tr>
<tr>
<td>$LC_COLLATE</td>
<td>它常常在.bashrc或/etc/profile文件里被设置，它控制文件名扩展和模式匹配的展开顺序。</td>
</tr>
<tr>
<td>$LINENO</td>
<td>这个变量表示在本shell脚本中该变量出现时所在的行数。它只在脚本中它出现时有意义，它一般可用于调试。</td>
</tr>
<tr>
<td>$MACHTYPE</td>
<td>机器类型，识别系统的硬件类型。</td>
</tr>
<tr>
<td>$OLDPWD</td>
<td>上一次工作的目录(“OLD-print-working-directory”,你上一次进入工作的目录)</td>
</tr>
<tr>
<td>$TZ</td>
<td>时区</td>
</tr>
<tr>
<td>$MAILCHECK</td>
<td>每隔多少秒检查是否有新的信件</td>
</tr>
<tr>
<td>$OSTYPE</td>
<td>操作系统类型</td>
</tr>
<tr>
<td>$MANPATH man</td>
<td>指令的搜寻路径</td>
</tr>
<tr>
<td>$PATH</td>
<td>可执行程序文件的搜索路径。一般有/usr/bin/, /usr/X11R6/bin/, /usr/local/bin,等等。</td>
</tr>
<tr>
<td>$PIPESTATUS</td>
<td>此数组变量保存了最后执行的前台管道的退出状态。相当有趣的是，它不一定和最后执行的命令的退出状态一样。</td>
</tr>
<tr>
<td>$PPID</td>
<td>一个进程的$PPID变量保存它的父进程的进程ID(pid)。用这个变量和pidof命令比较。</td>
</tr>
<tr>
<td>$PROMPT_COMMAND</td>
<td>这个变量在主提示符前($PS1显示之前)执行它的值里保存的命令。</td>
</tr>
<tr>
<td>$PS1</td>
<td>这是主提示符（第一提示符），它能在命令行上看见。</td>
</tr>
<tr>
<td>$PS2</td>
<td>副提示符（第二提示符），它在期望有附加的输入时能看见。它显示像”&gt;”的提示。</td>
</tr>
<tr>
<td>$PS3</td>
<td>第三提示符。它在一个select循环里显示 (参考例子 10-29)。</td>
</tr>
<tr>
<td>$PS4</td>
<td>第四提示符，它在用-x选项调用一个脚本时的输出的每一行开头显示。它通常显示像”+”的提示。</td>
</tr>
<tr>
<td>$PWD</td>
<td>工作目录(即你现在所处的目录) ，它类似于内建命令pwd。</td>
</tr>
<tr>
<td>$REPLY</td>
<td>没有变量提供给read命令时的默认变量．这也适用于select命令的目录，但只是提供被选择的变量项目编号而不是变量本身的值。</td>
</tr>
<tr>
<td>$SECONDS</td>
<td>脚本已运行的秒数。</td>
</tr>
<tr>
<td>$SHELLOPTS</td>
<td>已经激活的shell选项列表，它是一个只读变量。</td>
</tr>
<tr>
<td>$SHLVL</td>
<td>SHELL的嵌套级别．指示了Bash被嵌套了多深．在命令行里，$SHLVL是1，因此在一个脚本里，它是2</td>
</tr>
<tr>
<td>$TMOUT</td>
<td>如果$TMOUT环境变量被设为非零值时间值time，那么经过time这么长的时间后，shell提示符会超时．这将使此shell退出登录</td>
</tr>
<tr>
<td>$UID</td>
<td>用户ID号，这是当前用户的用户标识号，它在/etc/passwd文件中记录。</td>
</tr>
</tbody>
</table>
<h3 id="位置参数"><a href="#位置参数" class="headerlink" title="位置参数"></a>位置参数</h3><table>
<thead>
<tr>
<th>参数处理</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>$#</code></td>
<td>传递到脚本的参数个数</td>
</tr>
<tr>
<td><code>$*</code></td>
<td>以一个单字符串显示所有向脚本传递的参数。如”∗”用「”」括起来的情况、以”1 2…n”的形式输出所有参数。</td>
</tr>
<tr>
<td><code>$$</code></td>
<td>脚本运行的当前进程ID号</td>
</tr>
<tr>
<td><code>$!</code></td>
<td>后台运行的最后一个进程的ID号</td>
</tr>
<tr>
<td><code>$@</code></td>
<td>与∗相同，但是使用时加引号，并在引号中返回每个参数。如”@”用「”」括起来的情况、以”1””2” … “$n” 的形式输出所有参数。</td>
</tr>
<tr>
<td><code>$-</code></td>
<td>显示Shell使用的当前选项，与set命令功能相同。</td>
</tr>
<tr>
<td><code>$?</code></td>
<td>显示最后命令的退出状态。0表示没有错误，其他任何值表明有错误。</td>
</tr>
</tbody>
</table>
<h3 id="字串移动"><a href="#字串移动" class="headerlink" title="字串移动"></a>字串移动</h3><p><code>${string#substring}</code>从$string左边开始，剥去最短匹配$substring子串。<br><code>${string##substring}</code>从$string左边开始，剥去最长匹配$substring子串。<br><code>${string%substring}</code> 从$string结尾开始，剥去最短匹配$substring子串。<br><code>${string%%substring}</code>从$string结尾开始，剥去最长匹配$substring子串。  </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">String=abcABC123ABCabc</span><br><span class="line"><span class="meta">#</span><span class="bash">       ├----┘     ┆</span></span><br><span class="line"><span class="meta">#</span><span class="bash">       └----------┘</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String#a*C&#125;      # 123ABCabc</span><br><span class="line"><span class="meta">#</span><span class="bash"> 剥去匹配<span class="string">'a'</span>到<span class="string">'C'</span>之间最短的字符串.</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String##a*C&#125;     # abc</span><br><span class="line"><span class="meta">#</span><span class="bash"> 剥去匹配<span class="string">'a'</span>到<span class="string">'C'</span>之间最长的字符串.</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">String=abcABC123ABCabc</span><br><span class="line"><span class="meta">#</span><span class="bash">       ┆           ||</span></span><br><span class="line"><span class="meta">#</span><span class="bash">       └------------┘</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String%b*c&#125;      # abcABC123ABCa</span><br><span class="line"><span class="meta">#</span><span class="bash"> 从<span class="variable">$String</span>后面尾部开始，剥去匹配<span class="string">'a'</span>到<span class="string">'C'</span>之间最短的字符串.</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String%%b*c&#125;     # a</span><br><span class="line"><span class="meta">#</span><span class="bash"> 从<span class="variable">$String</span>后面尾部开始，剥去匹配<span class="string">'a'</span>到<span class="string">'C'</span>之间最长的字符串.</span></span><br></pre></td></tr></table></figure>
<h3 id="用awk处理字符串"><a href="#用awk处理字符串" class="headerlink" title="用awk处理字符串"></a>用awk处理字符串</h3><p>Bash脚本可以调用awk的字符串操作功能来代替它自己内建的字符串操作符</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">String=23skidoo1</span><br><span class="line"><span class="meta">#</span><span class="bash">      012345678    Bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash">      123456789    awk</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 注意上面两个程序对索引的不同处理:</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> Bash把字符串的第一个字符的标号称为<span class="string">'0'</span>。</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> Awk把字符串的第一个字符的标号称为<span class="string">'1'</span>。</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String:2:4&#125; # position 3 (0-1-2), 4 characters long</span><br><span class="line">                                         # skid</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 在awk中与Bash的<span class="variable">$&#123;string:pos:length&#125;</span>等同的是substr(string,pos,length)。</span></span><br><span class="line">echo | awk '&#123; </span><br><span class="line">  print substr("'"$&#123;String&#125;"'",3,4)      # skid</span><br><span class="line">&#125;'</span><br><span class="line"><span class="meta">#</span><span class="bash">  用一个空的<span class="string">"echo"</span>由管道传一个空的输入给awk,</span></span><br><span class="line"><span class="meta">#</span><span class="bash">+ 这样就不必提供一个文件名给awk。</span></span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h2 id="for-while"><a href="#for-while" class="headerlink" title="for/while"></a>for/while</h2><p>重复一些命令的代码块,如果条件不满足就退出循环。</p>
<h3 id="for"><a href="#for" class="headerlink" title="for"></a>for</h3><p>在循环的每次执行中，arg将顺序的存取list中列出的变量，下面是一个基本的循环结构。</p>
<blockquote>
<p>for arg in [list]<br>do<br>   command(s)…<br>done  </p>
</blockquote>
<p>每个<code>[list]</code>中的元素都可能包含多个参数，在处理参数组时，这是非常有用的，使用set命令来强制解析每个<code>[list]</code>中的元素。并且分配每个解析出来的部分到一个位置参数中。</p>
<p>循环的一个简单例子</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto</span><br><span class="line">do</span><br><span class="line">  echo $planet  # 每个行星被单独打印在一行上.</span><br><span class="line">done</span><br></pre></td></tr></table></figure>
<h3 id="while"><a href="#while" class="headerlink" title="while"></a>while</h3><p>一个while循环可以有多个判断条件，但是只有最后一个才能决定是否退出循环。然而这需要一种有点不同的循环语法。</p>
<blockquote>
<p>while [condition]<br>do<br>  command…<br>done  </p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> --------------------------</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 简单的<span class="keyword">while</span>循环</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> --------------------------</span></span><br><span class="line">var0=0</span><br><span class="line">LIMIT=10</span><br><span class="line"></span><br><span class="line">while [ "$var0" -lt "$LIMIT" ]</span><br><span class="line">do</span><br><span class="line">  echo -n "$var0 "        # -n 将会阻止产生新行。</span><br><span class="line"><span class="meta">  #</span><span class="bash">             ^           空格,数字之间的分隔。</span></span><br><span class="line">  var0=`expr $var0 + 1`   # var0=$(($var0+1))  也可以。</span><br><span class="line">                          # var0=$((var0 + 1)) 也可以。</span><br><span class="line">                          # let "var0 += 1"    也可以。</span><br><span class="line">done                      # 使用其他的方法也行。</span><br><span class="line"><span class="meta">#</span><span class="bash"> --------------------------</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 多条件的<span class="keyword">while</span>循环</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> --------------------------</span></span><br><span class="line">var1=unset</span><br><span class="line">previous=$var1</span><br><span class="line"></span><br><span class="line">while echo "previous-variable = $previous"</span><br><span class="line">      echo</span><br><span class="line">      previous=$var1</span><br><span class="line">      [ "$var1" != end ] # 记录之前的$var1.</span><br><span class="line">      # 这个"while"循环中有4个条件, 但是只有最后一个能控制循环.</span><br><span class="line">      # 退出状态由第4个条件决定.</span><br><span class="line">do</span><br><span class="line">echo "Input variable #1 (end to exit) "</span><br><span class="line">  read var1</span><br><span class="line">  echo "variable #1 = $var1"</span><br><span class="line">done </span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h3 id="until"><a href="#until" class="headerlink" title="until"></a>until</h3><p>这个结构在循环的顶部判断条件，并且如果条件一直为false那就一直循环下去。(与while相反)。</p>
<blockquote>
<p>until [condition-is-true]<br>do<br>  command…<br>done  </p>
</blockquote>
<p><strong>注意⚠️</strong></p>
<ol>
<li>until循环的判断在循环的顶部，这与某些编程语言是不同的。</li>
<li>与for循环一样，如果想把do和条件放在一行里，就使用”;”。</li>
</ol>
<blockquote>
<p>until [condition-is-true] ; do</p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">END_CONDITION=end</span><br><span class="line">until [ "$var1" = "$END_CONDITION" ]</span><br><span class="line"><span class="meta">#</span><span class="bash"> 在循环的顶部判断条件.</span></span><br><span class="line">do</span><br><span class="line">  echo "Input variable #1 "</span><br><span class="line">  echo "($END_CONDITION to exit)"</span><br><span class="line">  read var1</span><br><span class="line">  echo "variable #1 = $var1"</span><br><span class="line">done</span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h3 id="嵌套循环"><a href="#嵌套循环" class="headerlink" title="嵌套循环"></a>嵌套循环</h3><p>嵌套循环就是在一个循环中还有一个循环，内部循环在外部循环体中。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">outer=1             # 设置外部循环计数.</span><br><span class="line"><span class="meta">#</span><span class="bash"> 开始外部循环.</span></span><br><span class="line">for a in 1 2 3 4 5</span><br><span class="line">do</span><br><span class="line">  echo "Pass $outer in outer loop."</span><br><span class="line">  echo "---------------------"</span><br><span class="line">  inner=1           # 重设内部循环的计数.</span><br><span class="line"></span><br><span class="line"><span class="meta">  #</span><span class="bash"> ===============================================</span></span><br><span class="line"><span class="meta">  #</span><span class="bash"> 开始内部循环.</span></span><br><span class="line">  for b in 1 2 3 4 5</span><br><span class="line">  do</span><br><span class="line">    echo "Pass $inner in inner loop."</span><br><span class="line">    let "inner+=1"  # 增加内部循环计数.</span><br><span class="line">  done</span><br><span class="line"><span class="meta">  #</span><span class="bash"> 内部循环结束.</span></span><br><span class="line"><span class="meta">  #</span><span class="bash"> ===============================================</span></span><br><span class="line"></span><br><span class="line">  let "outer+=1"    # 增加外部循环的计数.</span><br><span class="line">  echo              # 每次外部循环之间的间隔.</span><br><span class="line">done               </span><br><span class="line"><span class="meta">#</span><span class="bash"> 外部循环结束.</span></span><br><span class="line"></span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h3 id="循环控制"><a href="#循环控制" class="headerlink" title="循环控制"></a>循环控制</h3><p>影响循环行为的命令 <code>break</code>， <code>continue</code>， break命令将会跳出循环，continue命令将会跳过本次循环下边的语句，直接进入下次循环。</p>
<p><strong>continue：</strong> continue命令与break命令类似，只有一点差别，它不会跳出所有循环，仅仅跳出当前循环。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">LIMIT=19  # 上限</span><br><span class="line"></span><br><span class="line">echo "Printing Numbers 1 through 20 (but not 3 and 11)."</span><br><span class="line"></span><br><span class="line">a=0</span><br><span class="line"></span><br><span class="line">while [ $a -le "$LIMIT" ]</span><br><span class="line">do</span><br><span class="line">  a=$(($a+1))</span><br><span class="line">  if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]  # Excludes 3 and 11.</span><br><span class="line">  then</span><br><span class="line">    continue      # 跳过本次循环剩下的语句.</span><br><span class="line">  fi</span><br><span class="line">  echo -n "$a "   # 在$a等于3和11的时候,这句将不会执行.</span><br><span class="line">done</span><br></pre></td></tr></table></figure>
<p><strong>break：</strong> break命令允许跳出所有循环（终止执行后面的所有循环）。</p>
<p>下面的例子中，脚本进入死循环直至用户输入数字大于5。要跳出这个循环，返回到shell提示符下，就要使用break命令。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">while :</span><br><span class="line">do</span><br><span class="line">    echo -n "Input a number between 1 to 5: "</span><br><span class="line">    read aNum</span><br><span class="line">    case $aNum in</span><br><span class="line">        1|2|3|4|5) echo "Your number is $aNum!"</span><br><span class="line">        ;;</span><br><span class="line">        *) echo "You do not select a number between 1 to 5, game is over!"</span><br><span class="line">            break</span><br><span class="line">        ;;</span><br><span class="line">    esac</span><br><span class="line">done</span><br></pre></td></tr></table></figure>
<p>⚠️ 在嵌套循环中，break 命令后面还可以跟一个整数，表示跳出第几层循环。例如：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">break n #表示跳出第 n 层循环。</span><br></pre></td></tr></table></figure>
<h2 id="case-select"><a href="#case-select" class="headerlink" title="case/select"></a>case/select</h2><p>case/select依靠在代码块的顶部或底部的条件判断来决定程序的分支。</p>
<h3 id="case"><a href="#case" class="headerlink" title="case"></a>case</h3><p>case它允许通过判断来选择代码块中多条路径中的一条。它的作用和多个if/then/else语句相同，是它们的简化结构，特别适用于创建目录。</p>
<blockquote>
<p>case “$variable” in<br>  ?”$condition1” )<br>  ?command…<br>  ?;;<br>  ?”$condition2” )<br>  ?command…<br>  ?;;<br>esac  </p>
</blockquote>
<ul>
<li>对变量使用<code>&quot;&quot;</code>并不是强制的，因为不会发生单词分离。</li>
<li>每句测试行，都以右小括号<code>)</code>结尾。</li>
<li>每个条件块都以两个分号结尾<code>;;</code>。</li>
<li>case块的结束以esac(case的反向拼写)结尾。</li>
</ul>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">clear # 清屏.</span><br><span class="line"></span><br><span class="line">echo "          我的简历"</span><br><span class="line">echo "          ------- "</span><br><span class="line">echo "下面通过shell脚本输出我的简历" </span><br><span class="line">echo</span><br><span class="line">echo "[B]asicinfo, 基本信息"</span><br><span class="line">echo "[E]ducation, 教育经历"</span><br><span class="line">echo "[I]tskill, IT 技能"</span><br><span class="line">echo</span><br><span class="line">read person</span><br><span class="line">case "$person" in</span><br><span class="line"><span class="meta">#</span><span class="bash"> 注意,变量是被引用的.</span></span><br><span class="line">  "B" | "b" )</span><br><span class="line"><span class="meta">  #</span><span class="bash"> 接受大写或小写输入.</span></span><br><span class="line">  echo</span><br><span class="line">  echo "小弟调调"</span><br><span class="line">  echo "手  机 : 136*****13"</span><br><span class="line">  echo "E-mail :wowohoo@qq.com"</span><br><span class="line">  echo "首  页 : http://JSLite.io"</span><br><span class="line">  ;;</span><br><span class="line"><span class="meta">  #</span><span class="bash"> 注意,在每个选项后边都需要以;;结尾.</span></span><br><span class="line"></span><br><span class="line">  "E" | "e" )</span><br><span class="line"><span class="meta">  #</span><span class="bash"> 接受大写或小写输入.</span></span><br><span class="line">  echo "■ 2003年9月 到 2006年8月"</span><br><span class="line">  echo "----------------------------"</span><br><span class="line">  echo "› 学校 : 野鸟高中"</span><br><span class="line">  echo "› 专业 : 艺术类"</span><br><span class="line">  echo "› 学历 : 高中"</span><br><span class="line">  ;;</span><br><span class="line"><span class="meta">  #</span><span class="bash"> 后边的[I]tskill的信息在这里就省略了.</span></span><br><span class="line">          * )</span><br><span class="line"><span class="meta">   #</span><span class="bash"> 默认选项.</span></span><br><span class="line"><span class="meta">   #</span><span class="bash"> 空输入(敲RETURN).</span></span><br><span class="line">   echo</span><br><span class="line">   echo "没有数据！"</span><br><span class="line">  ;;</span><br><span class="line">esac</span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h3 id="select"><a href="#select" class="headerlink" title="select"></a>select</h3><p>select结构是建立菜单的另一种工具，这种结构是从ksh中引入的。</p>
<blockquote>
<p>select variable [in list]<br>do<br>  ?command…<br>  ?break<br>done  </p>
</blockquote>
<p>用select来创建菜单</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">PS3='选择你喜欢的蔬菜: ' # 设置提示符字串.</span><br><span class="line"></span><br><span class="line">echo</span><br><span class="line">select vegetable in "豆" "胡萝卜" "土豆" "洋葱" "芜菁甘蓝"</span><br><span class="line">do</span><br><span class="line">  echo</span><br><span class="line">  echo "你最喜欢的蔬菜是 $vegetable 。"</span><br><span class="line">  echo "讨厌!"</span><br><span class="line">  echo</span><br><span class="line">  break  # 如果这里没有'break'会发生什么?</span><br><span class="line">done</span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<p>如果忽略了in list列表,那么select命令将使用传递到脚本的命令行参数($@),或者是函数参数(当select是在函数中时）与忽略in list时的for语句相比较：<strong>for variable [in list]</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">PS3='选择你喜欢的蔬菜:  '</span><br><span class="line">echo</span><br><span class="line">choice_of()&#123;</span><br><span class="line">  select vegetable</span><br><span class="line"><span class="meta">  #</span><span class="bash"> [<span class="keyword">in</span> list] 被忽略, 所以<span class="string">'select'</span>用传递给函数的参数.</span></span><br><span class="line">  do</span><br><span class="line">    echo</span><br><span class="line">    echo "你最喜欢的蔬菜是  $vegetable。"</span><br><span class="line">    echo "讨厌!"</span><br><span class="line">    echo</span><br><span class="line">    break</span><br><span class="line">  done</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">choice_of "豆" "米饭" "胡萝卜" "土豆" "洋葱" "芜菁甘蓝"</span><br><span class="line"><span class="meta">#</span><span class="bash">         <span class="variable">$1</span>   <span class="variable">$2</span>     <span class="variable">$3</span>      <span class="variable">$4</span>    <span class="variable">$5</span>     <span class="variable">$6</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash">         传递给choice_of() 函数的参数</span></span><br><span class="line"></span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><p>和”真正的”编程语言一样，Bash也有函数，虽然在某些实现方面稍有些限制。 一个函数是一个子程序，用于实现一串操作的代码块(code block)，它是完成特定任务的”黑盒子”。 当有重复代码，当一个任务只需要很少的修改就被重复几次执行时, 这时你应考虑使用函数。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">function function_name &#123; </span><br><span class="line">  command... </span><br><span class="line">&#125; </span><br><span class="line"><span class="meta">#</span><span class="bash"> 或</span></span><br><span class="line">function_name () &#123; </span><br><span class="line">  command... </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>在一个函数内嵌套另一个函数也是可以的，但是不常用。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">f1 ()&#123;</span><br><span class="line">  f2 ()&#123; # nested</span><br><span class="line">    echo "Function \"f2\", inside \"f1\"."</span><br><span class="line">  &#125;</span><br><span class="line">&#125;  </span><br><span class="line">f2  #  引起错误.</span><br><span class="line">    #  就是你先"declare -f f2"了也没用.</span><br><span class="line"></span><br><span class="line">f1  #  什么也不做,因为调用"f1"不会自动调用"f2".</span><br><span class="line">f2  #  现在,可以正确的调用"f2"了,</span><br><span class="line">    #+ 因为之前调用"f1"使"f2"在脚本中变得可见了.</span><br></pre></td></tr></table></figure>
<h3 id="局部变量"><a href="#局部变量" class="headerlink" title="局部变量"></a>局部变量</h3><p>如果变量用local来声明，那么它只能在该变量声明的代码块(block of code)中可见，这个代码块就是局部”范围”。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 在函数内部的全局和局部变量.</span></span><br><span class="line">func ()</span><br><span class="line">&#123;</span><br><span class="line">  local loc_var=23       # 声明为局部变量.</span><br><span class="line">  echo                   # 使用内建的'local'关键字.</span><br><span class="line">  echo "\"loc_var\" in function = $loc_var"</span><br><span class="line">  global_var=999         # 没有声明为局部变量.</span><br><span class="line">                         # 默认为全局变量. </span><br><span class="line">  echo "\"global_var\" in function = $global_var"</span><br><span class="line">&#125;  </span><br><span class="line"></span><br><span class="line">func</span><br><span class="line"><span class="meta">#</span><span class="bash"> 现在，来看看是否局部变量<span class="string">"loc_var"</span>能否在函数外面可见.</span></span><br><span class="line">echo "\"loc_var\" outside function = $loc_var"</span><br><span class="line">                                   # $loc_var outside function = </span><br><span class="line">                                   # 不, $loc_var不是全局可访问的.</span><br><span class="line">echo "\"global_var\" outside function = $global_var"</span><br><span class="line">                                      # $global_var outside function = 999</span><br><span class="line">                                      # $global_var 是全局可访问的.</span><br><span class="line">exit 0</span><br><span class="line"><span class="meta">#</span><span class="bash">  与In contrast to C相比, 在函数内声明的Bash变量只有在</span></span><br><span class="line"><span class="meta">#</span><span class="bash">+ 它被明确声明成局部的变量时才是局部的</span></span><br></pre></td></tr></table></figure>
<p>⚠️ ：在函数调用之前，所有在函数内声明且没有明确声明为local的变量都可在函数体外可见</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">func ()&#123;</span><br><span class="line">  global_var=37    #  在函数还没有被调用前</span><br><span class="line">                   #+ 变量只在函数内可见. </span><br><span class="line">&#125;                  #  函数结束</span><br><span class="line">echo "global_var = $global_var"  # global_var =</span><br><span class="line">                                 #  函数"func"还没有被调用,</span><br><span class="line">                                 #+ 所以变量$global_var还不能被访问.</span><br><span class="line">func</span><br><span class="line">echo "global_var = $global_var"  # global_var = 37</span><br><span class="line">                                 # 已经在函数调用时设置了值.</span><br></pre></td></tr></table></figure>
<h3 id="函数参数"><a href="#函数参数" class="headerlink" title="函数参数"></a>函数参数</h3><p>在Shell中，调用函数时可以向其传递参数。在函数体内部，通过 <code>$n</code> 的形式来获取参数的值，例如，$1表示第一个参数，$2表示第二个参数</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">funWithParam()&#123;</span><br><span class="line">    echo "第一个参数为 $1 !"</span><br><span class="line">    echo "第二个参数为 $2 !"</span><br><span class="line">    echo "第十个参数为 $10 !"</span><br><span class="line">    echo "第十个参数为 $&#123;10&#125; !"</span><br><span class="line">    echo "第十一个参数为 $&#123;11&#125; !"</span><br><span class="line">    echo "参数总数有 $# 个!"</span><br><span class="line">    echo "作为一个字符串输出所有参数 $* !"</span><br><span class="line">&#125;</span><br><span class="line">funWithParam 1 2 3 4 5 6 7 8 9 34 73</span><br></pre></td></tr></table></figure>
<h3 id="函数返回值"><a href="#函数返回值" class="headerlink" title="函数返回值"></a>函数返回值</h3><p>定义一个带有return语句的函数。函数返回值在调用该函数后通过 <code>$?</code> 来获得。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">funWithReturn()&#123;</span><br><span class="line">    echo "这个函数会对输入的两个数字进行相加运算..."</span><br><span class="line">    echo "输入第一个数字: "</span><br><span class="line">    read aNum</span><br><span class="line">    echo "输入第二个数字: "</span><br><span class="line">    read anotherNum</span><br><span class="line">    echo "两个数字分别为 $aNum 和 $anotherNum !"</span><br><span class="line">    return $(($aNum+$anotherNum))</span><br><span class="line">&#125;</span><br><span class="line">funWithReturn</span><br><span class="line">echo "输入的两个数字之和为 $? !"</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 这个函数会对输入的两个数字进行相加运算...</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 输入第一个数字: </span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 1</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 输入第二个数字: </span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 2</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 两个数字分别为 1 和 2 !</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 输入的两个数字之和为 3 !</span></span><br></pre></td></tr></table></figure>
<p>⚠️ <code>$10</code> 不能获取第十个参数，获取第十个参数需要${10}。当n&gt;=10时，需要使用${n}来获取参数。</p>
<p><strong>特殊字符用来处理参数：</strong></p>
<table>
<thead>
<tr>
<th>参数处理</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>$#</td>
<td>传递到脚本的参数个数</td>
</tr>
<tr>
<td>$*</td>
<td>以一个单字符串显示所有向脚本传递的参数</td>
</tr>
<tr>
<td>$$</td>
<td>脚本运行的当前进程ID号</td>
</tr>
<tr>
<td>$!</td>
<td>后台运行的最后一个进程的ID号</td>
</tr>
<tr>
<td>$@</td>
<td>与$*相同，但是使用时加引号，并在引号中返回每个参数。</td>
</tr>
<tr>
<td>$-</td>
<td>显示Shell使用的当前选项，与set命令功能相同。</td>
</tr>
<tr>
<td>$?</td>
<td>显示最后命令的退出状态。0表示没有错误，其他任何值表明有错误。</td>
</tr>
</tbody>
</table>
<h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2><h3 id="测试结构"><a href="#测试结构" class="headerlink" title="测试结构"></a>测试结构</h3><p>一个if/then结构能包含嵌套的比较和测试。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">echo "Testing \"false\""</span><br><span class="line">if [ "false" ]              #  "false"是一个字符串.</span><br><span class="line">then</span><br><span class="line">  echo "\"false\" is true." #+ 它被测试为真.</span><br><span class="line">else</span><br><span class="line">  echo "\"false\" is false."</span><br><span class="line">fi            # "false"为真.</span><br></pre></td></tr></table></figure>
<p>Else if 和 elif</p>
<p>elif是else if的缩写。作用是在一个if/then里嵌入一个内部的if/then结构。</p>
<p><code>[[]]</code>结构比Bash版本的<code>[]</code>更通用。用<code>[[ ... ]]</code>测试结构比用<code>[ ... ]</code>更能防止脚本里的许多逻辑错误。比如说，<code>&amp;&amp;</code>,<code>||</code>,<code>&lt;</code>和<code>&gt;</code>操作符能在一个<code>[[]]</code>测试里通过，但在<code>[]</code>结构会发生错误。</p>
<p><code>(( ))</code>结构扩展并计算一个算术表达式的值。如果表达式值为0，会返回1或假作为退出状态码。一个非零值的表达式返回一个0或真作为退出状态码。这个结构和先前test命令及<code>[]</code>结构的讨论刚好相反。</p>
<h3 id="文件测试操作符"><a href="#文件测试操作符" class="headerlink" title="文件测试操作符"></a>文件测试操作符</h3><p>如果下面的条件成立返回真。</p>
<table>
<thead>
<tr>
<th>操作符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>-e</td>
<td>文件存在</td>
</tr>
<tr>
<td>-a</td>
<td>文件存在，这个和-e的作用一样. 它是不赞成使用的，所以它的用处不大。</td>
</tr>
<tr>
<td>-f</td>
<td>文件是一个普通文件(不是一个目录或是一个设备文件)</td>
</tr>
<tr>
<td>-s</td>
<td>文件大小不为零</td>
</tr>
<tr>
<td>-d</td>
<td>文件是一个目录</td>
</tr>
<tr>
<td>-b</td>
<td>文件是一个块设备(软盘，光驱，等等。)</td>
</tr>
<tr>
<td>-c</td>
<td>文件是一个字符设备(键盘，调制解调器，声卡，等等。)</td>
</tr>
<tr>
<td>-p</td>
<td>文件是一个管道</td>
</tr>
<tr>
<td>-h</td>
<td>文件是一个符号链接</td>
</tr>
<tr>
<td>-L</td>
<td>文件是一个符号链接</td>
</tr>
<tr>
<td>-S</td>
<td>文件是一个socket</td>
</tr>
<tr>
<td>-t</td>
<td>文件(描述符)与一个终端设备相关。</td>
</tr>
<tr>
<td>-r</td>
<td>文件是否可读 (指运行这个测试命令的用户的读权限)</td>
</tr>
<tr>
<td>-w</td>
<td>文件是否可写 (指运行这个测试命令的用户的读权限)</td>
</tr>
<tr>
<td>-x</td>
<td>文件是否可执行 (指运行这个测试命令的用户的读权限)</td>
</tr>
<tr>
<td>-g</td>
<td>文件或目录的设置-组-ID(sgid)标记被设置。</td>
</tr>
<tr>
<td>-u</td>
<td>文件的设置-用户-ID(suid)标志被设置</td>
</tr>
<tr>
<td>-k</td>
<td>粘住位设置</td>
</tr>
<tr>
<td>-N</td>
<td>文件最后一次读后被修改</td>
</tr>
<tr>
<td>f1 -nt f2</td>
<td>文件f1比f2新</td>
</tr>
<tr>
<td>f1 -ot f2</td>
<td>文件f1比f2旧</td>
</tr>
<tr>
<td>f1 -ef f2</td>
<td>文件f1和f2 是相同文件的硬链接</td>
</tr>
<tr>
<td>!</td>
<td>“非” – 反转上面所有测试的结果(如果没有给出条件则返回真)。</td>
</tr>
</tbody>
</table>
<p><strong>注意⚠️</strong></p>
<ol>
<li><code>-t</code> 这个测试选项可以用于检查脚本中是否标准输入 ([ -t 0 ])或标准输出([ -t 1 ])是一个终端。</li>
<li><code>-g</code> 如果一个目录的sgid标志被设置，在这个目录下创建的文件都属于拥有此目录的用户组，而不必是创建文件的用户所属的组。这个特性对在一个工作组里的同享目录很有用处。</li>
</ol>
<h3 id="比较操作符"><a href="#比较操作符" class="headerlink" title="比较操作符"></a>比较操作符</h3><p>二元比较操作符比较两个变量或是数值。注意整数和字符串比较的分别。</p>
<p><strong>整数比较</strong></p>
<table>
<thead>
<tr>
<th>比较操作符</th>
<th>描述</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>-eq</code></td>
<td>等于</td>
<td><code>if [ &quot;$a&quot; -eq &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td><code>-ne</code></td>
<td>不等于</td>
<td><code>if [ &quot;$a&quot; -ne &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td><code>-gt</code></td>
<td>大于</td>
<td><code>if [ &quot;$a&quot; -gt &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td><code>-ge</code></td>
<td>大于等于</td>
<td><code>if [ &quot;$a&quot; -ge &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td><code>-lt</code></td>
<td>小于</td>
<td><code>if [ &quot;$a&quot; -lt &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td><code>-le</code></td>
<td>小于等于</td>
<td><code>if [ &quot;$a&quot; -le &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td><code>&lt;</code></td>
<td>小于(在双括号里使用)</td>
<td><code>((&quot;$a&quot; &lt; &quot;$b&quot;))</code></td>
</tr>
<tr>
<td><code>&lt;=</code></td>
<td>小于等于 (在双括号里使用)</td>
<td><code>((&quot;$a&quot; &lt;= &quot;$b&quot;))</code></td>
</tr>
<tr>
<td><code>&gt;</code></td>
<td>大于 (在双括号里使用)</td>
<td><code>((&quot;$a&quot; &gt; &quot;$b&quot;))</code></td>
</tr>
<tr>
<td><code>&gt;=</code></td>
<td>大于等于(在双括号里使用)</td>
<td><code>((&quot;$a&quot; &gt;= &quot;$b&quot;))</code></td>
</tr>
</tbody>
</table>
<p><strong>字符串比较</strong></p>
<table>
<thead>
<tr>
<th>比较操作符</th>
<th>描述</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td>=</td>
<td>等于</td>
<td><code>if [ &quot;$a&quot; = &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td>==</td>
<td>等于，它和=是同义词。</td>
<td><code>if [ &quot;$a&quot; == &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td>!=</td>
<td>不相等，操作符在[[ … ]]结构里使用模式匹配.</td>
<td><code>if [ &quot;$a&quot; != &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td>&lt;</td>
<td>小于，依照ASCII字符排列顺序，注意”&lt;”字符在[ ] 结构里需要转义</td>
<td><code>if [[ &quot;$a&quot; &lt; &quot;$b&quot; ]]</code> <code>if [ &quot;$a&quot; \&lt; &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td>&gt;</td>
<td>大于，依照ASCII字符排列顺序，注意”&gt;”字符在[ ] 结构里需要转义.</td>
<td><code>if [[ &quot;$a&quot; &gt; &quot;$b&quot; ]]</code> <code>if [ &quot;$a&quot; \&gt; &quot;$b&quot; ]</code></td>
</tr>
<tr>
<td>-z</td>
<td>字符串为”null”，即是指字符串长度为零。</td>
<td>-</td>
</tr>
<tr>
<td>-n</td>
<td>字符串不为”null”，即长度不为零。</td>
<td>-</td>
</tr>
</tbody>
</table>
<p><strong>混合比较</strong></p>
<table>
<thead>
<tr>
<th>比较操作符</th>
<th>描述</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td>-a</td>
<td>逻辑与，如果exp1和exp2都为真，则exp1 -a exp2返回真。</td>
<td><code>if [ &quot;$exp1&quot; -a &quot;$exp2&quot; ]</code></td>
</tr>
<tr>
<td>-o</td>
<td>逻辑或，只要exp1和exp2任何一个为真，则exp1 -o exp2 返回真。</td>
<td><code>if [ &quot;$exp1&quot; -o &quot;$exp2&quot; ]</code></td>
</tr>
</tbody>
</table>
<p>在一个混合测试中，把一个字符串变量引号引起来可能还不够。如果$string变量是空的话，表达式<code>[ -n &quot;$string&quot; -o &quot;$a&quot; = &quot;$b&quot; ]</code>在一些Bash版本中可能会引起错误。安全的办法是附加一个外部的字符串给可能有空字符串变量比较的所有变量，<code>[ &quot;x$string&quot; != x -o &quot;x$a&quot; = &quot;x$b&quot; ]</code> (x字符可以互相抵消)</p>
<h2 id="操作字符串"><a href="#操作字符串" class="headerlink" title="操作字符串"></a>操作字符串</h2><p>Bash已经支持了令人惊讶的字符串操作的数量。不一致的命令语法和冗余的功能，导致真的学起来有困难。</p>
<h3 id="字符串长度"><a href="#字符串长度" class="headerlink" title="字符串长度"></a>字符串长度</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">String=abcABC123ABCabc</span><br><span class="line"></span><br><span class="line">echo $&#123;#String&#125;                 # 15</span><br><span class="line">echo `expr length $String`      # 15</span><br><span class="line">echo `expr "$String" : '.*'`    # 15</span><br></pre></td></tr></table></figure>
<p>匹配字符串开头的字串的长度，下面两种方法的 $substring 是一个正则表达式。</p>
<p><code>expr match &quot;$string&quot; &#39;$substring&#39;</code><br><code>expr &quot;$string&quot; : &#39;$substring&#39;</code>   </p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">String=abcABC123ABCabc</span><br><span class="line"><span class="meta">#</span><span class="bash">       └------┘</span></span><br><span class="line"><span class="meta">#</span><span class="bash">       </span></span><br><span class="line">echo `expr match "$String" 'abc[A-Z]*.2'`   # 8</span><br><span class="line">echo `expr "$String" : 'abc[A-Z]*.2'`       # 8</span><br></pre></td></tr></table></figure>
<h3 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h3><p><code>expr index $string $substring</code> 在字符串$string中$substring第一次出现的数字位置</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">String=abcABC123ABCabc</span><br><span class="line">echo `expr index "$String" C12`             # 6</span><br><span class="line">                                             # C 字符的位置.</span><br><span class="line"></span><br><span class="line">echo `expr index "$String" 1c`              # 3</span><br><span class="line"><span class="meta">#</span><span class="bash"> <span class="string">'c'</span> (<span class="keyword">in</span> <span class="comment">#3 position) matches before '1'.</span></span></span><br></pre></td></tr></table></figure>
<h3 id="字串提取"><a href="#字串提取" class="headerlink" title="字串提取"></a>字串提取</h3><p><code>${string:position}</code> 把$string中从第$postion个字符开始字符串提取出来。如果$string是”*”或”@”，则表示从位置参数中提取第$postion后面的字符串。<br><code>${string:position:length}</code> 把$string中$postion个字符后面的长度为$length的字符串提取出来。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 字串提取</span></span><br><span class="line">String=abcABC123ABCabc</span><br><span class="line"><span class="meta">#</span><span class="bash">       0123456789.....</span></span><br><span class="line"><span class="meta">#</span><span class="bash">       以0开始计算.</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String:0&#125;                            # abcABC123ABCabc</span><br><span class="line">echo $&#123;String:1&#125;                            # bcABC123ABCabc</span><br><span class="line">echo $&#123;String:7&#125;                            # 23ABCabc</span><br><span class="line">echo $&#123;String:7:3&#125;                          # 23A</span><br><span class="line">                                            # 提取的字串长为3</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 有没有可能从字符串的右边结尾处提取?</span></span><br><span class="line">    </span><br><span class="line">echo $&#123;String:-4&#125;                           # abcABC123ABCabc</span><br><span class="line"><span class="meta">#</span><span class="bash"> 默认是整个字符串，就相当于<span class="variable">$&#123;parameter:-default&#125;</span>.</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 然而. . .</span></span><br><span class="line"></span><br><span class="line">echo $&#123;String:(-4)&#125;                         # Cabc </span><br><span class="line">echo $&#123;String: -4&#125;                          # Cabc</span><br><span class="line"><span class="meta">#</span><span class="bash"> 这样,它可以工作了.</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 圆括号或附加的空白字符可以转义<span class="variable">$position</span>参数.</span></span><br></pre></td></tr></table></figure>
<h2 id="转义字符"><a href="#转义字符" class="headerlink" title="转义字符"></a>转义字符</h2><p>在单个字符前面的转义符<code>\</code>告诉shell不必特殊解释这个字符，只把它当成字面上的意思。但在一些命令和软件包里，比如说echo和sed,转义一个字符可能会引起一个相反的效果－－因为它们可能触发那个字符的特殊意思。</p>
<p><code>\r</code> 回车<br><code>\n</code> 换行<br><code>\c</code> 不换行<br><code>\t</code> 水平制表符<br><code>\v</code> 垂直制表符<br><code>\a</code> 表示“警告”（蜂鸣或是闪动）<br><code>\\</code> 反斜杠字符<br><code>\0ddd</code> 将自负表示成1到3的八进制数值  </p>
<h2 id="退出-退出状态"><a href="#退出-退出状态" class="headerlink" title="退出/退出状态"></a>退出/退出状态</h2><p><code>$?</code> 变量用于测试脚本中的命令执行结果非常的有用。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">echo hello</span><br><span class="line">echo $?    # 因为上一条命令执行成功，打印0。</span><br><span class="line"></span><br><span class="line">lskdf      # 无效命令。</span><br><span class="line">echo $?    # 因为上面的无效命令执行失败，打印一个非零的值。</span><br><span class="line"></span><br><span class="line">exit 113   # 返回113状态码给shell。</span><br><span class="line">           # 可以运行脚本结束后立即执行命令"echo $?" 检验。</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash">  依照惯例,命令<span class="string">'exit 0'</span>表示执行成功,</span></span><br><span class="line"><span class="meta">#</span><span class="bash">  当产生一个非零退出值时表示一个错误或是反常的条件。</span></span><br></pre></td></tr></table></figure>
<h3 id="变量间接引用"><a href="#变量间接引用" class="headerlink" title="变量间接引用"></a>变量间接引用</h3><p>假设一个变量的值是第二个变量的名字。这样要如何才能从第一个变量处重新获得第二个变量的值？例如，<code>a=letter_of_alphabet</code>和<code>letter_of_alphabet=z</code>，是否能由a引用得到z ? 这确实可以办到，这种技术被称为间接引用。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">a=letter_of_alphabet   # 变量"a"保存着另外一个变量的名字.</span><br><span class="line">letter_of_alphabet=z</span><br><span class="line"><span class="meta">#</span><span class="bash"> 直接引用.</span></span><br><span class="line">echo "a = $a"          # a = letter_of_alphabet</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 间接引用.</span></span><br><span class="line">eval a=\$$a</span><br><span class="line">echo "Now a = $a"      # 现在 a = z</span><br><span class="line">exit 0</span><br></pre></td></tr></table></figure>
<h3 id="双括号结构"><a href="#双括号结构" class="headerlink" title="双括号结构"></a>双括号结构</h3><p>用<code>((...))</code>结构来使用C风格操作符来处理变量。<a href="./example/demo26">demo26</a></p>
<p><code>`</code>shell
(( a = 23 ))  # 以C风格来设置一个值，在”=”两边可以有空格.
echo “a (initial value) = $a”</p>
<p>(( a++ ))     # C风格的计算后自增.
echo “a (after a++) = $a”</p>
<p>(( a– ))     # C风格的计算后自减.
echo “a (after a–) = $a”</p>
<p>(( ++a ))     # C风格的计算前自增.
echo “a (after ++a) = $a”</p>
<p>(( –a ))     # C风格的计算前自减.
echo </p>

      
    </div>
    
    
    

    <div>
      
        <div>
    
        <div class="text-center line pages-end">
				<span>本文结束<i class="fa fa-meh-o fa-fw"></i>感谢您的阅读</span>
        </div>
    
</div>
      
    </div>

    <div>
      
        
<div class="my_post_copyright">
  <script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script>
  <!-- JS库 sweetalert 可修改路径 -->
  <script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.7.1/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/sweetalert@1.0.0/dist/sweetalert.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/sweetalert@1.0.0/dist/sweetalert.css">
  <p><span>本文标题:</span><a href="/2020/Shell入门教程.html">Shell入门教程</a></p>
  <p><span>文章作者:</span><a href="/" title="访问 陈宇（cosyer） 的个人博客">陈宇（cosyer）</a></p>
  <p><span>发布时间:</span>2020年03月23日 - 01:03</p>
  <p><span>最后更新:</span>2020年04月29日 - 01:04</p>
  <p><span>原始链接:</span><a href="/2020/Shell入门教程.html" title="Shell入门教程">http://mydearest.cn/2020/Shell入门教程.html</a>
    <span class="copy-path"  title="点击复制文章链接"><i class="fa fa-clipboard" data-clipboard-text="http://mydearest.cn/2020/Shell入门教程.html"  aria-label=" 复制成功！"></i></span>
  </p>
  <p><span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
</div>
<script> 
    var clipboard = new Clipboard('.fa-clipboard');
    clipboard.on('success', $(function(){
      $(".fa-clipboard").click(function(){
        swal({
          title: "",     
          text: '复制成功',   
          timer: 500,
          showConfirmButton: false
        });
      });
    }));  
</script>

      
    </div>

    

    
      <div>
        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
  <div>坚持原创技术分享，您的支持将鼓励我继续创作！</div>
  <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
    <span>赏</span>
  </button>
  <div id="QR" style="display: none;">

    
      <div id="wechat" style="display: inline-block">
        <img id="wechat_qr" src="/images/wechatpay.png" alt="陈宇（cosyer） WeChat Pay"/>
        <p>WeChat Pay</p>
      </div>
    

    
      <div id="alipay" style="display: inline-block">
        <img id="alipay_qr" src="/images/alipay.png" alt="陈宇（cosyer） Alipay"/>
        <p>Alipay</p>
      </div>
    

    

  </div>
</div>

      </div>
    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/shell/" rel="tag"><i class="fa fa-tag fa-fw"></i> shell</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2020/Angular组件通讯.html" rel="next" title="Angular组件通讯">
                <i class="fa fa-chevron-left"></i> Angular组件通讯
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2020/观察者模式VS发布订阅模式.html" rel="prev" title="观察者模式VS发布订阅模式">
                观察者模式VS发布订阅模式 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
            
  <div class="comments" id="comments">
    
      <div class="comments v" id="comments"></div>
    
  </div>


          
        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/images/avatar.jpg"
               alt="陈宇（cosyer）" />
          <p class="site-author-name" itemprop="name">陈宇（cosyer）</p>
           
              <p class="site-description motion-element" itemprop="description">不去做的话永远也做不到。</p>
           
        </div>
        <nav class="site-state motion-element">

          
            <div class="site-state-item site-state-posts">
              <a href="/archives/">
                <span class="site-state-item-count">134</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-categories">
              <a href="/categories/index.html">
                <span class="site-state-item-count">7</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-tags">
              <a href="/tags/index.html">
                <span class="site-state-item-count">55</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        
          <div class="feed-link motion-element">
            <a href="/rss2.xml" rel="alternate">
              <i class="fa fa-rss"></i>
              RSS
            </a>
          </div>
        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a rel="external nofollow" href="https://github.com/cosyer" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                    
                      GitHub
                    
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a rel="external nofollow" href="https://twitter.com/yzchenyu1995" target="_blank" title="Twitter">
                  
                    <i class="fa fa-fw fa-twitter"></i>
                  
                    
                      Twitter
                    
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a rel="external nofollow" href="mailto:yzchenyu1995@gmail.com" target="_blank" title="E-Mail">
                  
                    <i class="fa fa-fw fa-envelope"></i>
                  
                    
                      E-Mail
                    
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a rel="external nofollow" href="https://www.facebook.com/profile.php?id=100025666071215" target="_blank" title="FB Page">
                  
                    <i class="fa fa-fw fa-facebook"></i>
                  
                    
                      FB Page
                    
                </a>
              </span>
            
          
        </div>

        
        

        
        
          <div class="links-of-blogroll motion-element links-of-blogroll-inline">
            <div class="links-of-blogroll-title">
              <i class="fa  fa-fw fa-globe"></i>
              推荐阅读
            </div>
            <ul class="links-of-blogroll-list">
              
                <li class="links-of-blogroll-item">
                  <a rel="external nofollow" href="http://callmesoul.cn" title="Callmesoul" target="_blank">Callmesoul</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a rel="external nofollow" href="https://www.jstips.co/" title="JsTips" target="_blank">JsTips</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a rel="external nofollow" href="http://dir.mydearest.cn/motion/" title="Personal Site" target="_blank">Personal Site</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a rel="external nofollow" href="http://resume.mydearest.cn/" title="Resume" target="_blank">Resume</a>
                </li>
              
            </ul>
          </div>
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#脚本运行"><span class="nav-number">1.</span> <span class="nav-text">脚本运行</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#注释"><span class="nav-number">2.</span> <span class="nav-text">注释</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#命令分隔符"><span class="nav-number">3.</span> <span class="nav-text">命令分隔符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#结束符"><span class="nav-number">4.</span> <span class="nav-text">结束符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#句号-圆点"><span class="nav-number">5.</span> <span class="nav-text">句号/圆点</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#引号"><span class="nav-number">6.</span> <span class="nav-text">引号</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#单引号"><span class="nav-number">6.1.</span> <span class="nav-text">单引号</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#双引号"><span class="nav-number">6.2.</span> <span class="nav-text">双引号</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#命令替换"><span class="nav-number">7.</span> <span class="nav-text">命令替换</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#操作符"><span class="nav-number">8.</span> <span class="nav-text">操作符</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#赋值"><span class="nav-number">8.1.</span> <span class="nav-text">赋值</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#计算操作符"><span class="nav-number">8.2.</span> <span class="nav-text">计算操作符</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#位操作符"><span class="nav-number">8.3.</span> <span class="nav-text">位操作符</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#逻辑操作符"><span class="nav-number">8.4.</span> <span class="nav-text">逻辑操作符</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#逗号操作符"><span class="nav-number">8.5.</span> <span class="nav-text">逗号操作符</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#变量"><span class="nav-number">9.</span> <span class="nav-text">变量</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#变量值"><span class="nav-number">9.1.</span> <span class="nav-text">变量值</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#定义变量"><span class="nav-number">9.2.</span> <span class="nav-text">定义变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#只读变量"><span class="nav-number">9.3.</span> <span class="nav-text">只读变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#使用变量"><span class="nav-number">9.4.</span> <span class="nav-text">使用变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#删除变量unset"><span class="nav-number">9.5.</span> <span class="nav-text">删除变量unset</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#变量类型"><span class="nav-number">9.6.</span> <span class="nav-text">变量类型</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#内部变量"><span class="nav-number">9.7.</span> <span class="nav-text">内部变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#位置参数"><span class="nav-number">9.8.</span> <span class="nav-text">位置参数</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#字串移动"><span class="nav-number">9.9.</span> <span class="nav-text">字串移动</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#用awk处理字符串"><span class="nav-number">9.10.</span> <span class="nav-text">用awk处理字符串</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#for-while"><span class="nav-number">10.</span> <span class="nav-text">for/while</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#for"><span class="nav-number">10.1.</span> <span class="nav-text">for</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#while"><span class="nav-number">10.2.</span> <span class="nav-text">while</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#until"><span class="nav-number">10.3.</span> <span class="nav-text">until</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#嵌套循环"><span class="nav-number">10.4.</span> <span class="nav-text">嵌套循环</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#循环控制"><span class="nav-number">10.5.</span> <span class="nav-text">循环控制</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#case-select"><span class="nav-number">11.</span> <span class="nav-text">case/select</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#case"><span class="nav-number">11.1.</span> <span class="nav-text">case</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#select"><span class="nav-number">11.2.</span> <span class="nav-text">select</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#函数"><span class="nav-number">12.</span> <span class="nav-text">函数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#局部变量"><span class="nav-number">12.1.</span> <span class="nav-text">局部变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数参数"><span class="nav-number">12.2.</span> <span class="nav-text">函数参数</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#函数返回值"><span class="nav-number">12.3.</span> <span class="nav-text">函数返回值</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#测试"><span class="nav-number">13.</span> <span class="nav-text">测试</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#测试结构"><span class="nav-number">13.1.</span> <span class="nav-text">测试结构</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#文件测试操作符"><span class="nav-number">13.2.</span> <span class="nav-text">文件测试操作符</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#比较操作符"><span class="nav-number">13.3.</span> <span class="nav-text">比较操作符</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#操作字符串"><span class="nav-number">14.</span> <span class="nav-text">操作字符串</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#字符串长度"><span class="nav-number">14.1.</span> <span class="nav-text">字符串长度</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#索引"><span class="nav-number">14.2.</span> <span class="nav-text">索引</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#字串提取"><span class="nav-number">14.3.</span> <span class="nav-text">字串提取</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#转义字符"><span class="nav-number">15.</span> <span class="nav-text">转义字符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#退出-退出状态"><span class="nav-number">16.</span> <span class="nav-text">退出/退出状态</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#变量间接引用"><span class="nav-number">16.1.</span> <span class="nav-text">变量间接引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#双括号结构"><span class="nav-number">16.2.</span> <span class="nav-text">双括号结构</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">陈宇（cosyer）</span>
</div>
<div>
 <span class="alive"></span>
 </div>
<div class="powered-by">
  <i class="fa fa-users fa-fw"></i>
  <span id="busuanzi_container_site_uv">
    终于等到你(UV): <span id="busuanzi_value_site_uv"></span>
  </span>
  &nbsp;&nbsp;|&nbsp;&nbsp;
  <i class="fa fa-bar-chart-o fa-fw"></i>
  <span id="busuanzi_container_site_pv">
    欢迎再来(PV): <span id="busuanzi_value_site_pv"></span>
  </span>

  <div class="theme-info">
    <div class="powered-by"></div>
    <span class="post-count">Blog总字数: 234.6k字</span>
  </div>

  <div class="theme-info">
    <div class="powered-by"></div>
    <a class="post-count" href="http://www.beian.miit.gov.cn/" target="_blank">苏ICP备17005342号-1</a>
  </div>
</div>

<!--


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Mist
  </a>
</div>

-->

        

        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>
<script type="text/javascript" src="https://cdn.lishaoy.net/js/index.js"></script>

















  


  
  

  
  



  


  


  




	





  






  <script src="https://cdn.lishaoy.net/js/av-min.js"></script>
  
  <script src='https://cdn.lishaoy.net/js/Valine.min.js'></script>

  <script type="text/javascript">
    var GUEST = ['nick','mail','link'];
    var guest = '';
    guest = guest.split(',').filter(item=>{
      return GUEST.indexOf(item)>-1;
    });
    new Valine({
        av: AV,
        el: '#comments' ,
        appId: 'SKflNaQWS70153r2kOqgcGge-gzGzoHsz',
        appKey: 'gE9ySnRyOkS4UNzYJ7GOCa56',
        placeholder: '想说点什么 ：）',
        avatar: 'retro'
    });
  </script>



  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.json";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0&&datas.length>0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content =  data.content&&data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content&&content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text&&text.toLowerCase();
                        word = word&&word.toLowerCase();
                      }
                      while ((position = text&&text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>




  

  
  <script src="https://cdn.lishaoy.net/js/av-core-mini-0.6.4.js"></script>
  <script>AV.initialize("SKflNaQWS70153r2kOqgcGge-gzGzoHsz", "gE9ySnRyOkS4UNzYJ7GOCa56");</script>
  <script>
    function showTime(Counter) {
      var query = new AV.Query(Counter);
      var entries = [];
      var $visitors = $(".leancloud_visitors");

      $visitors.each(function () {
        entries.push( $(this).attr("id").trim() );
      });

      query.containedIn('url', entries);
      query.find()
        .done(function (results) {
          var COUNT_CONTAINER_REF = '.leancloud-visitors-count';

          if (results.length === 0) {
            $visitors.find(COUNT_CONTAINER_REF).text(0);
            return;
          }

          for (var i = 0; i < results.length; i++) {
            var item = results[i];
            var url = item.get('url');
            var time = item.get('time');
            var element = document.getElementById(url);

            $(element).find(COUNT_CONTAINER_REF).text(time);
          }
          for(var i = 0; i < entries.length; i++) {
            var url = entries[i];
            var element = document.getElementById(url);
            var countSpan = $(element).find(COUNT_CONTAINER_REF);
            if( countSpan.text() == '') {
              countSpan.text(0);
            }
          }
        })
        .fail(function (object, error) {
          console.log("Error: " + error.code + " " + error.message);
        });
    }

    function addCount(Counter) {
      var $visitors = $(".leancloud_visitors");
      var url = $visitors.attr('id').trim();
      var title = $visitors.attr('data-flag-title').trim();
      var query = new AV.Query(Counter);

      query.equalTo("url", url);
      query.find({
        success: function(results) {
          if (results.length > 0) {
            var counter = results[0];
            counter.fetchWhenSave(true);
            counter.increment("time");
            counter.save(null, {
              success: function(counter) {
                var $element = $(document.getElementById(url));
                $element.find('.leancloud-visitors-count').text(counter.get('time'));
              },
              error: function(counter, error) {
                console.log('Failed to save Visitor num, with error message: ' + error.message);
              }
            });
          } else {
            var newcounter = new Counter();
            /* Set ACL */
            var acl = new AV.ACL();
            acl.setPublicReadAccess(true);
            acl.setPublicWriteAccess(true);
            newcounter.setACL(acl);
            /* End Set ACL */
            newcounter.set("title", title);
            newcounter.set("url", url);
            newcounter.set("time", 1);
            newcounter.save(null, {
              success: function(newcounter) {
                var $element = $(document.getElementById(url));
                $element.find('.leancloud-visitors-count').text(newcounter.get('time'));
              },
              error: function(newcounter, error) {
                console.log('Failed to create');
              }
            });
          }
        },
        error: function(error) {
          console.log('Error:' + error.code + " " + error.message);
        }
      });
    }

    $(function() {
      var Counter = AV.Object.extend("Counter");
      if ($('.leancloud_visitors').length == 1) {
        addCount(Counter);
      } else if ($('.post-title-link').length > 1) {
        showTime(Counter);
      }
    });
  </script>



  

  

  
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src=""></script>
  


  

  


  <div id="load" style=""></div>
  <!-- 新增看娘
  <script async src="/live2dw/js/perTips.js"></script>
  <script src="/live2dw/lib/L2Dwidget.min.js"></script>
  -->
  <!-- 页面点击小红心
  <script type="text/javascript" src="/js/src/love.js"></script>
  -->

  <!-- 背景动画
  <script type="text/javascript" src="/js/src/particle.js"></script>
  -->

   <!-- 输入爆炸效果来自 http://xiaowiba.com （小尾巴） 如有侵权，请通知我撤销
  <script type="text/javascript" src="/js/src/activate-power-mode.js"></script>
  -->

   <!-- UV、PV统计 不蒜子
   <script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>
  -->
  <script type="text/javascript" src="https://cdn.lishaoy.net/js/all-min-d98fa596b6.js"></script>
   <!-- 自己的脚本
  <script type="text/javascript" src="/js/src/cosyer.js"></script>
  -->
  <script>
// 下雪
//(function($){$.fn.snow=function(options){var $flake=$('<div id="flake" />').css({'position':'absolute','top':'-50px'}).html('&#10052;'),documentHeight=$(document).height(),documentWidth=$(document).width(),defaults={minSize:10,maxSize:20,newOn:500,flakeColor:"#FFFFFF"},options=$.extend({},defaults,options);var interval=setInterval(function(){var startPositionLeft=Math.random()*documentWidth-100,startOpacity=0.5+Math.random(),sizeFlake=options.minSize+Math.random()*options.maxSize,endPositionTop=documentHeight-40,endPositionLeft=startPositionLeft-100+Math.random()*200,durationFall=documentHeight*10+Math.random()*5000;$flake.clone().appendTo('body').css({left:startPositionLeft,opacity:startOpacity,'font-size':sizeFlake,color:options.flakeColor}).animate({top:endPositionTop,left:endPositionLeft,opacity:0.2},durationFall,'linear',function(){$(this).remove()});},options.newOn);};})(jQuery);
//$.fn.snow({ minSize: 5, maxSize: 50, newOn: 1000, flakeColor: '#00F' });

// 点线连接
!function () { function o(w, v, i) { return w.getAttribute(v) || i } function j(i) { return document.getElementsByTagName(i) } function l() { var i = j("script"), w = i.length, v = i[w - 1]; return { l: w, z: o(v, "zIndex", -1), o: o(v, "opacity", 1), c: o(v, "color", "255, 255, 255"), n: o(v, "count", 99) } } function k() { r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight } function b() { e.clearRect(0, 0, r, n); var w = [f].concat(t); var x, v, A, B, z, y; t.forEach(function (i) { i.x += i.xa, i.y += i.ya, i.xa *= i.x > r || i.x < 0 ? -1 : 1, i.ya *= i.y > n || i.y < 0 ? -1 : 1, e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1); for (v = 0; v < w.length; v++) { x = w[v]; if (i !== x && null !== x.x && null !== x.y) { B = i.x - x.x, z = i.y - x.y, y = B * B + z * z; y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A / 2, e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke()) } } w.splice(w.indexOf(i), 1) }), m(b) } var u = document.createElement("canvas"), s = l(), c = "c_n" + s.l, e = u.getContext("2d"), r, n, m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (i) { window.setTimeout(i, 1000 / 45) }, a = Math.random, f = { x: null, y: null, max: 20000 }; u.id = c; u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o; j("body")[0].appendChild(u); k(), window.onresize = k; window.onmousemove = function (i) { i = i || window.event, f.x = i.clientX, f.y = i.clientY }, window.onmouseout = function () { f.x = null, f.y = null }; for (var t = [], p = 0; s.n > p; p++) { var h = a() * r, g = a() * n, q = 2 * a() - 1, d = 2 * a() - 1; t.push({ x: h, y: g, xa: q, ya: d, max: 6000 }) } setTimeout(function () { b() }, 100) }();

// 崩溃欺骗
var OriginTitle = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
    if (document.hidden) {
        $('[rel="icon"]').attr('href', "/img/TEP.ico");
        document.title = '╭(°A°`)╮ 页面崩溃啦 ~';
        clearTimeout(titleTime);
    }
    else {
        $('[rel="icon"]').attr('href', "/favicon.ico");
        document.title = '(ฅ>ω<*ฅ) 噫又好了~' + OriginTitle;
        titleTime = setTimeout(function () {
            document.title = OriginTitle;
        }, 2000);
    }
});

// 存活时间
var aliveList=document.getElementsByClassName("alive")
setInterval(function() { 
var time = new Date(); 
// 程序计时的月从0开始取值后+1 
//根据自己博客的创建时间更改数值 
var t = "博客存活了"+Math.floor((+new Date - 1527868800000) / (1000 * 60 * 60 * 24)) + "天 " + time.getHours() + "小时" 
+ time.getMinutes() + "分" + time.getSeconds() + "秒"; 
aliveList[0].innerHTML = t; 
}, 1000); 
// 统计页面加载时间
window.onload = function () {
  var loadTime = window.performance.timing.domContentLoadedEventEnd-window.performance.timing.navigationStart; 
  console.log('Page load time is '+ loadTime);
}
</script>
  <script> $(function(){ $('#loader').css('display','none');});</script>
<style>
    .comments.no-post {
      background: transparent;
    }
    .no-post.v *{
      color: #ddd;
    }
    .v .vlist p {
      margin: 12px 0;
    }
    .v .vbtn {
      background: #fbfbfb;
      padding: .3rem 1.2em;
      border: 1px solid #dddddd75;
    }
    .no-post.v .vbtn {
      background: #2222220a;
    }
    .no-post.v .vbtn:active, .no-post.v .vbtn:hover {
      background-color: #fff;
    }
    .no-post.v .vwrap {
      border: 1px solid #f0f0f036;;
    }
    .no-post.v a {
      color: #ddd;
    }
    .v ul {
      padding-left: 25px;
    }
    .v ul li {
      list-style: disc;
      padding: 2px 15px 0 0;
    }
    .v .vlist strong , .vinput.vpreview strong {
        color: #87daff;
        font-size: 108%;
    }
    .v .vlist .vcard .vhead .vsys {
        background: #87daff17;
        color: #aaa;
        border: 1px solid #87daff1f;
        padding: 1px 5px;
        font-size: 12px;
        line-height: 1.4;
    }

    .no-post.v .vlist .vcard .vhead .vsys{
      background: #ededed1f;
      color: #808080;
      padding: 1px 5px;
      font-size: 12px;
      line-height: 1.4;
      border: none;
    }

    .v .vlist .vcard .vcontent a {
      color: #86dbff;
      border-bottom-color: #86dbff99;
    }

    .v .vlist .vcard .vcontent a:hover {
        color: #d7191a;
        border-bottom-color: #222;
    }

    .no-post.v .vlist .vcard section {
        border-bottom: 1px dashed #f5f5f55e;
    }

    .v .vwrap .vheader .vinput {
        width: 33.33%;
        border-bottom: 1px dashed #dedede45;
    }
    .no-post.v .vwrap .vheader .vinput::-webkit-input-placeholder {
        color: #808080;
    }
    .no-post.v .vwrap .vheader .vinput:-ms-input-placeholder{  /* Internet Explorer 10-11 */
        color: #808080;
    }
    .v .txt-right {
        display: none;
    }

    .v .vlist .vcard .vcontent .code, .v .vlist .vcard .vcontent code, .v .vlist .vcard .vcontent pre , .vinput.vpreview code , .vinput.vpreview pre {
      color: #005098fc;
      background: #87daffb8;
      border-radius: 4px;
      box-shadow: 0 0 2px #87daff;
      font-size: 90%;
      padding: 2px 6px;
    }
    .v .vlist .vcard .vcontent img {
      max-width: 18px;
      display: inline-block;
    }

    .v .vlist .vcard .vcontent img{
      max-width:18px;
      display:inline-block
    }

    .v .vwrap .vheader .vinput:focus {
      border-bottom: 1px solid #87daff;
    }
    .v .vlist .vcard .vcontent pre , .vinput.vpreview pre {
        background: #87daff21;
        border-radius: 4px;
        box-shadow: 0 0 2px #ffffff33;
    }
    .v .vlist .vcard .vcontent pre code ,.vinput.vpreview pre code {
        color: #87daff;
        background: #87daff00;
        border-radius: 4px;
        box-shadow: 0 0 2px #87daff05;
    }
    .v .vlist .vcard .vcontent.expand:after {
      color: #ff0000de;
      font-size: 110%;
      font-weight: bold;
      background: #87daff38;
      border-bottom-right-radius: 4px;
      border-bottom-left-radius: 4px;
    }
    .comments.no-post .vlist .vcard .vcontent.expand:after {
      color: #fff;
    }
    @media screen and (max-width: 414px) {
        .v .vlist {
            padding-left: 0;
        }
    }
    .v .vlist .vcard .vcontent.expand:before {
        background: linear-gradient(180deg,hsla(0, 0%, 100%, 0),hsla(199, 100%, 76%, 0.22));
        background: -webkit-gradient(linear,left top,left bottom,from(hsla(0,0%,100%,0)),to(hsla(199, 100%, 76%, 0.22));
    }
</style>

</body>
</html>
